package com.project.business.service.impl;

import com.baomidou.mybatisplus.solon.service.impl.ServiceImpl;
import com.project.business.entity.FileEntity;
import com.project.business.mapper.FileEntityMapper;
import com.project.business.entity.constant.FileType;
import com.project.business.service.FileEntityService;
import com.project.core.jwt.AuditAware;
import com.project.core.util.FileUtils;
import com.common.exception.ErrCode;
import com.common.exception.SeException;
import com.project.properties.CustomProperties;
import org.noear.solon.annotation.Component;
import org.noear.solon.annotation.Inject;
import org.noear.solon.core.handle.UploadedFile;
import org.noear.solon.data.annotation.Tran;

import java.io.File;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;

@Component
public class FileEntityServiceImpl extends ServiceImpl<FileEntityMapper, FileEntity>
        implements FileEntityService {

    @Inject
    private CustomProperties customProperties;

    @Override
    public FileEntity getOneById(Integer id) {
        ErrCode.Request_Param.nonNull(id, "文件id不能为空！");
        FileEntity fileEntity = this.getById(id);
        ErrCode.Request_Param.nonNull(fileEntity, "该文件不存在！");
        return fileEntity;
    }

    @Override
    public FileEntity upload(UploadedFile upFile) throws RuntimeException {
        FileEntity info = new FileEntity();
        try {
            // fileName utf8 处理上传文件名称
            // 先decode转码，在用char转码
            String fileName = upFile.getName();
            // 兼容处理 RFC 6266规范 上传 文件编码格式
            String fileNamePrefix = "UTF-8''";
            boolean charFlag = fileName.contains(fileNamePrefix);
            if (charFlag) {
                fileName = URLDecoder.decode(fileName.replace(fileNamePrefix, ""), StandardCharsets.UTF_8);
            } else {
                fileName = new String(fileName.getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8);
            }

            // file full path
            String filePath = customProperties.getFilePathPrefix() + fileName;

            // save file
            upFile.transferTo(new File(filePath));

            FileType type = FileUtils.getFileType(fileName);

            info.setName(fileName);
            info.setType(type);
            info.setFilePath(filePath);
            info.setSize(upFile.getContentSize());
            info.setUserId(AuditAware.userId());
            info.setCreateTime(LocalDateTime.now());
            info.setUpdatedTime(LocalDateTime.now());

            this.save(info);
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            try {
                upFile.delete();
            }catch (Exception e){
                // 这里不做任何处理
            }
        }
        // 返回文件元数据
        return info;
    }

    @Override
    public File download(Integer id) {
        FileEntity entity = getOneById(id);

        String filePath = entity.getFilePath();

        return new File(filePath);
    }

    @Override
    public File preview(Integer id) {
        FileEntity entity = getOneById(id);

        String filePath = entity.getFilePath();
        FileType type = FileUtils.getFileType(filePath);

        if (FileType.Pdf != type && FileType.Pic != type) {
            // 假装做判断
            throw new SeException(ErrCode.Request_Param, "该文件类型不支持预览查看！");
        }

        return new File(filePath);
    }

    @Override
    @Tran
    public void del(Integer id) {
        FileEntity entity = getOneById(id);

        String filePath = entity.getFilePath();

        // 删除数据
        this.removeById(id);

        // 删除服务器实体文件
        File file = new File(filePath);
        file.delete();
    }
}




